package server

import (
	"bytes"
	"io"
	"net/http"
	"time"

	slog "gitee.com/simplexyz/simplego/log"
)

const (
	DefaultMinDispatchInterval = 0 * time.Millisecond
	DefaultTimeout             = 60 * time.Second
)

type HandlerOption struct {
	minDispatchInterval time.Duration
	timeout             time.Duration
	queued              bool
}

func (o HandlerOption) MinDispatchInterval() time.Duration {
	return o.minDispatchInterval
}

func (o HandlerOption) Timeout() time.Duration {
	return o.timeout
}

type HandleOptionFunc func(option *HandlerOption)

func WithMinDispatchInterval(minDispatchInterval time.Duration) HandleOptionFunc {
	return func(option *HandlerOption) {
		option.minDispatchInterval = minDispatchInterval
	}
}

func WithTimeout(timeout time.Duration) HandleOptionFunc {
	return func(option *HandlerOption) {
		option.timeout = timeout
	}
}

func WithRequestQueued(queued bool) HandleOptionFunc {
	return func(option *HandlerOption) {
		option.queued = queued
	}
}

func NewHandlerOption(optionFuncs ...HandleOptionFunc) *HandlerOption {
	option := &HandlerOption{
		minDispatchInterval: DefaultMinDispatchInterval,
		timeout:             DefaultTimeout,
		queued:              true,
	}
	for _, f := range optionFuncs {
		f(option)
	}
	return option
}

func TraceRequestBody(logger slog.ILogger) HandlerFunc {
	return func(ctx *Context) {
		data, err := ctx.GetRawData()
		if err != nil {
			logger.Errorf("[%s] get request data fail, %s", ctx.Request.URL.Path, err)
			ctx.AbortWithStatus(http.StatusBadRequest)
			return
		}

		logger.Debugf("[%s] request data=[%s]", ctx.Request.URL.Path, data)

		ctx.Request.Body = io.NopCloser(bytes.NewBuffer(data))
	}
}
